Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Implement ldvirtftn in shared generic contexts #2339

Merged
merged 3 commits into from
Dec 15, 2016

Conversation

MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Dec 13, 2016

This is to unblock #2308.
Requires JIT changes from dotnet/coreclr#8608.

This is two commits: first one is a bugfix uncovered by #2308. The second implements a missing feature required to support ldvirtftn in shared generic context.

I'm also restricting the number of cases when we actually need a generic lookup to calls/ldftn of interfaces and generic virtual methods. Normal virtual method calls/ldvirtfn go through the vtable slots that are the same between various canonically equivalent instantiations and don't need a runtime lookup.

On Project N, generic dictionaries point to the interface dispatch cell. The process of invoking/loading-the-address-of an interface method consists of a generic lookup for the interface dispatch cell, followed by a call to RhpResolveInterfaceMethod. This doesn't map great to what RyuJIT does (generic lookup followed by "mov rcx, this / call resultOfGenericLookup"). I'm making the dictionary point to a stub to do the dispatch for now. This has obvious delegate equivalency problems. I'll be filing an issue for the feature work to fix this.

Dependency analysis was incorrectly assuming these have their own
dictionary (they don't).
@MichalStrehovsky
Copy link
Member Author

Cc @mikedn

Copy link
Member

@davidwrighton davidwrighton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good except for the bits I asked you to tweak.

public override ISymbolNode GetTarget(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
MethodDesc instantiatedMethod = _method.InstantiateSignature(typeInstantiation, methodInstantiation);
return factory.ReadyToRunHelper(ReadyToRunHelperId.VirtualCall, instantiatedMethod);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put in a comment describing why this shouldn't be here... Something like, the function pointer returned should be the result of the virtual dispatch, not a pointer to the virtual dispatcher.

@@ -2683,23 +2683,33 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO
(void*)ObjectToHandle(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.ResolveGenericVirtualMethod, targetMethod));
pResult.nullInstanceCheck = false;
}
else if ((flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_LDFTN) != 0)
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the structure to fold together the virtual and non-virtual dispatch paths. While that is a simplification for now(since we only have R2R codegen), it is not in touch with longer term direction where we'll want to have more optimized codegen that handles the various cases in the most optimal form.

@MichalStrehovsky
Copy link
Member Author

@dotnet-bot test this please

@MichalStrehovsky MichalStrehovsky merged commit 8246678 into dotnet:master Dec 15, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants